'''
pyDuinoAPI : Python Arduino API : Pin Types module
author:     Steve De Jongh ( dejongh[dot]st[at]gmail[dot]com )
Licence type: MIT

Copyright (c) 2013 Steve De Jongh (dejongh[dot]st[at]gmail[dot]com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
'''

from constants import *

class Pin(object):
    """
    General Pin Object. Used as parent for AnalogPin and DigitalPin object only!
    """
    def __init__(self, name):
        self.name = name
        self.used = False

    def used(self):
        '''
        Usagle: myPin.used()
        Defines a pin as in use
        '''
        self.used = True

    def unused(self):
        '''
        Usagle: myPin.unused()
        Defines a pin as not in use
        '''
        self.used = False

#-------------------------------------------------------------

class AnalogPin(Pin):
    """
    AnalogPin Object
    Usage: myanalogPin = AnalogPin(name)
        (name of the pin on the Arduino Board)
    """
    def __init__(self, name):
        super(AnalogPin,self).__init__(name)
        self._state = LOW
        self._value = 0

    def read(self):
        """
        Usage: value = myAnalogPin.read()
        Returns the value of the pin ranging from 0 to 1023
        """
        return self._value

#-------------------------------------------------------------

class DigitalPin(Pin):
    """
    Digital Pin Object
    Usage: myDigitalPin = DigitalPin(name)
        (name of the pin on the Arduino Board)
    """
    def __init__(self, name):
        super(DigitalPin,self).__init__(name)
        self._mode = OUTPUT
        self._state = LOW

    def getMode(self):
        """
        Usage: myDigitalPin.getMode()
        Returns working mode ofor the pin.
        True = OUTPUT
        False = INPUT
        """
        return self._mode

    def inputMode(self):
        """
        Usage: myDigitalPin.InputMode()
        Sets the given pin to input mode
        """
        self._mode = INPUT

    def outputMode(self):
        """
        Usage: myDigitalPin.OutMode()
        Sets the given pin to output mode
        """
        self._mode = OUTPUT

    def setHigh(self):
        """
        Usage: myDigitalPin.setHigh()
        Sets the given pin to HIGH state
        """
        self._state = HIGH

    def setLow(self):
        """
        Usage: myDigitalPin.setLow()
        Sets the given pin to LOW state
        """
        self._state = LOW

    def pullup(self,value):
        """
        Usage: myAnalogPin.pullup(True|False)
        Enable or disable pullup resistor
        """
        if value == True:
            self._state = HIGH
        else:
            self._state = LOW
            
    def read(self):
        """
        Usage: value = myDigitalPin.read()
        Returns current state of the pin, 255 for HIGH and 0 for LOW
        """
        return self._state 

    def reset(self):
        """
        Usage: mydigitalPin.reset()
        Resets pin to defaults value (OUTPUT and LOW)
        """
        self.setLow()
        self.outputMode()

#-------------------------------------------------------------

class PwmPin(DigitalPin):
    """
    Digital Pin with PWM capabilities Object
    Usage: PwmPin(name)
        (name of the pin on the Arduino Board)
    """
    def __init__(self, name):
        super(PwmPin,self).__init__(name)
        self._state = LOW
        self.outputMode()

    def setValue(self,value=0):
        """
        Usage: myDigitalPin.setValue(x)
        Sets the output PWM, integer ranging from 0 to 255
        """
        if self._state >= 0 and self._state <= 255:
            self._state = int(value)
